package com.mc.fastkit.log

import android.util.Log
import org.json.JSONArray
import org.json.JSONObject

/**
 * Log打印工具
 * @author: MasterChan
 * @date: 2022-05-28 23:20
 */
object LogUtils {

    var tag = "LogUtils"
        private set
    var isDebug = true
        private set
    var isSaveLog = false
        private set
    var printer: IPrinter = Printer()
        private set
    var logManager: ILogManager = LogManager()
        private set

    fun setTag(tag: String) = apply {
        this.tag = tag
    }

    fun setDebug(debug: Boolean) = apply {
        this.isDebug = debug
    }

    fun setSaveLog(saveLog: Boolean) = apply {
        this.isSaveLog = saveLog
    }

    fun setPrinter(printer: IPrinter) = apply {
        this.printer = printer
    }

    fun setLogManager(logManager: ILogManager) = apply {
        this.logManager = logManager
    }

    fun v(vararg content: Any?) {
        v(tag, *content)
    }

    fun v(tag: String, vararg content: Any?) {
        print(Priority.VERBOSE, tag, null, *content)
    }

    fun d(vararg content: Any?) {
        d2(tag, *content)
    }

    fun d2(tag: String, vararg content: Any?) {
        print(Priority.DEBUG, tag, null, * content)
    }

    fun i(vararg content: Any?) {
        i2(tag, *content)
    }

    fun i2(tag: String, vararg content: Any?) {
        print(Priority.INFO, tag, null, * content)
    }

    fun w(vararg content: Any?) {
        w2(tag, *content)
    }

    fun w2(tag: String, vararg content: Any?) {
        print(Priority.WARN, tag, null, *content)
    }

    fun e(vararg content: Any?) {
        e2(tag, *content)
    }

    fun e2(tag: String, vararg content: Any?) {
        print(Priority.ERROR, tag, null, *content)
    }

    fun wtf(vararg content: Any?) {
        wtf2(tag, *content)
    }

    fun wtf2(tag: String, vararg content: Any?) {
        print(Priority.ASSERT, tag, null, *content)
    }

    /**
     * 打印日志
     * @param priority 日志等级
     * @param tag String
     * @param content Any?
     * @param stackTrace 自定义显示的堆栈
     */
    fun print(
        @Priority priority: Int,
        tag: String,
        stackTrace: StackTraceElement? = null,
        vararg content: Any?,
    ) {
        var newContent = ""
        if (content.isNotEmpty()) {
            newContent = content.joinToString { it.parseToString() }
        }
        if (isDebug) {
            printer.println(priority, tag, newContent, stackTrace)
        }
        if (isSaveLog) {
            logManager.save(newContent)
        }
    }

    /**
     * 删除过期日志
     */
    fun deleteOverdue() {
        logManager.deleteOverdue()
    }

    /**
     * 将Any解析为String
     */
    private fun Any?.parseToString(): String {
        return when (this) {
            is String -> parseString(this)
            is Array<*> -> contentToString()
            is IntArray -> contentToString()
            is FloatArray -> contentToString()
            is DoubleArray -> contentToString()
            is LongArray -> contentToString()
            is ShortArray -> contentToString()
            is ByteArray -> contentToString()
            is CharArray -> contentToString()
            is Throwable -> Log.getStackTraceString(this)
            else -> toString()
        }
    }

    /**
     * 解析String，判断是否是json格式
     * @param content String
     * @return String
     */
    private fun parseString(content: String): String {
        return when {
            content.startsWith("{") && content.endsWith("}") -> {
                try {
                    JSONObject(content).toString(2)
                } catch (e: Exception) {
                    e.printStackTrace()
                    content
                }
            }

            content.startsWith("[") && content.endsWith("]") -> {
                try {
                    JSONArray(content).toString(2)
                } catch (e: Exception) {
                    e.printStackTrace()
                    content
                }
            }

            else -> content
        }
    }
}